import { Scene } from '@babylonjs/core/scene';
import { Control } from '@babylonjs/gui/2D/controls/control';
import { Button } from '@babylonjs/gui/2D/controls/button';
import { IUIRectangleOptions, UIRectangle } from './ui-rectangle';
import { CreateHandleTo, IHandle, RemoveHandle } from '../../data/data-handle';
import { Rectangle } from '@babylonjs/gui/2D/controls/rectangle';


/**
 * 选择框控件
 * @param text 文字内容
 * @param imageUrl 图像地址
 * @param fontFamily 字体
 * @param fontSize 字体大小
 * @param fontColor 字体颜色
 * @param selected 是否选中
 */
interface IUISelectGridOptions extends IUIRectangleOptions {
    text?: string,
    imageUrl?: string,
    fontFamily?: string,
    fontSize?: number,
    fontColor?: string,
    selected?: boolean,
}


/**
 * 选择框控件
 * @param name 名称
 * @param scene 所在场景
 * @param options 参数对象
 */
class UISelectGrid extends UIRectangle {

    private _thickness!: number;
    private _changeHandles: Array<IHandle<boolean>> = [];
    private _url!: string | null;

    constructor(name: string, scene: Scene, options?: IUISelectGridOptions) {
        super(name, scene, options);
        const ops = options || {};
        this.isSelected = ops.selected || false;
    }

    /**
     * 设置是否选中
     */
    public set isSelected(isSelected: boolean) {
        if (this.isSelected === isSelected) return;
        (this.control as Button).thickness = isSelected ? this._thickness : 0;
        if (!this.avoidEventHandle) this._changeHandles.forEach(handle => handle.callback(isSelected));
    }

    /**
     * 获取是否选中
     */
    public get isSelected(): boolean {
        return !!(this.control as Button).thickness;
    }

    /**
     * 添加选中状态改变时的回调函数对象
     * @param func 回调函数
     * @returns 回调函数对象
     */
    public onChange(func: { (isSelected: boolean): void }): IHandle<boolean> {
        return CreateHandleTo(func, this._changeHandles);
    }

    /**
     * 移除选中状态改变时的回调函数对象
     * @param handle 回调函数对象或其id
     */
    public removeChangeHandle(handle: number | IHandle<boolean>): void {
        RemoveHandle(handle, this._changeHandles);
    }

    protected initializeControl(name: string, scene: Scene, options: IUISelectGridOptions): Button {
        this._url = options.imageUrl || null;
        const grid = this._url ?
            Button.CreateImageOnlyButton(name + '-grid', this._url) :
            Button.CreateSimpleButton(name + '-grid', options.text || 'grid');
        grid.color = options.fontColor || '#ffffff';
        grid.fontFamily = options.fontFamily || 'Arial';
        grid.fontSize = options.fontSize || 26;
        grid.background = options.background || '#000000';
        grid.cornerRadius = options.cornerRadius || 0;
        grid.thickness = 0;
        this._thickness = Math.max(options.borderThickness || 0, 1);

        return grid;
    }

    protected bindEvent(control: Control, options: IUISelectGridOptions): void {
        super.bindEvent(control as Rectangle, options);
        (this.control as Button).onPointerClickObservable.add(() => {
            if (!this.isEnabled) return;
            this.isSelected = !this.isSelected;
            if (!this.avoidEventHandle) this._changeHandles.forEach(handle => handle.callback(this.isSelected));
        });
    }

    protected unbindEvent(control: Control): void {
        super.unbindEvent(control);
        (this.control as Button).onPointerClickObservable.clear();
    }

}


/**
 * 创建选择框控件
 * @param name 名称
 * @param scene 所在场景
 * @param options 参数对象
 * @param changeCallback 选中状态改变时的回调函数
 * @returns 选择框控件
 */
const CreateUISelectGrid = (name: string, scene: Scene, options: IUISelectGridOptions, changeCallback?: { (isChecked: boolean): void }): UISelectGrid => {
    const grid = new UISelectGrid(name, scene, options);
    if (changeCallback) grid.onChange(changeCallback);
    return grid;
};


export { UISelectGrid, CreateUISelectGrid };
export type { IUISelectGridOptions };